package com.wisezone.workflow.exec;

import java.util.Date;
import java.util.List;
import java.util.Timer;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.wisezone.common.mail.Attachment;
import com.wisezone.common.mail.MailBean;
import com.wisezone.common.mail.MailSenderService;
import com.wisezone.workflow.bean.WfActivity;
import com.wisezone.workflow.bean.WfActivityInstUser;
import com.wisezone.workflow.bean.WfActivityInstance;
import com.wisezone.workflow.bean.form.WfVariableForm;
import com.wisezone.workflow.bean.form.WfVariableInstanceForm;
import com.wisezone.workflow.bean.search.WfActivityInstUserSearch;
import com.wisezone.workflow.bean.search.WfActivityInstanceSearch;
import com.wisezone.workflow.bean.search.WfVariableInstanceSearch;
import com.wisezone.workflow.bean.search.WfVariableSearch;
import com.wisezone.workflow.core.ActivityInstance;
import com.wisezone.workflow.core.FlowEngine;
import com.wisezone.workflow.core.ProcessInstance;
import com.wisezone.workflow.dao.WfActivityInstUserDao;
import com.wisezone.workflow.dao.WfActivityInstanceDao;
import com.wisezone.workflow.dao.WfVariableDao;
import com.wisezone.workflow.dao.WfVariableInstanceDao;
import com.wisezone.workflow.exception.WfCoreException;
import com.wisezone.workflow.exception.WfExecException;

/**
 * 活动运行辅助类 2010-10-26
 * 
 * @author shan
 * 
 */
public class ActivityExecHelper {

	/**
	 * 活动用户组分配转用户分配
	 * 
	 * @param wfActivityInstUserDao
	 * @param processInstId
	 * @param currentActivityInst
	 * @throws WfExecException
	 */
	public static void groupToUserSave(
			WfActivityInstUserDao wfActivityInstUserDao, Long processInstId,
			ActivityInstance currentActivityInst) throws WfExecException {

		WfActivityInstUserSearch aiuSearch = new WfActivityInstUserSearch();
		aiuSearch.setActivityInstId(currentActivityInst.getModel().getId());
		aiuSearch.setUserId(currentActivityInst.getModel().getActor());
		WfActivityInstUser wfAiu = wfActivityInstUserDao.get(aiuSearch);
		if (wfAiu == null) { // 原来是用户组分配人(没有用户userId)
			wfAiu = new WfActivityInstUser();
			wfAiu.setActivityInstId(currentActivityInst.getModel().getId());
			wfAiu.setProcessInstId(processInstId);
			wfAiu.setUserId(currentActivityInst.getModel().getActor());
			wfActivityInstUserDao.save(wfAiu);
		}
	}

	/**
	 * 并发活动处理
	 * 
	 * @param currentActivityInst
	 * @param processInstId
	 * @param wfActivityInstanceDao
	 * @return
	 * @throws WfExecException
	 */
	public static boolean concActivityExec(
			ActivityInstance currentActivityInst, Long processInstId,
			WfActivityInstanceDao wfActivityInstanceDao)
			throws WfExecException {

		boolean canCreateNext = false;
		WfActivityInstanceSearch aiSearch = new WfActivityInstanceSearch();
		aiSearch.setActivityId(currentActivityInst.getActivity().getModel()
				.getId());
		aiSearch.setProcessInstId(processInstId);
		List<WfActivityInstance> aiList = wfActivityInstanceDao
				.listAll(aiSearch);
		Object passNum = currentActivityInst
				.getVariable(FlowEngine.CONN_PASS_NUM);
		Object isPass = currentActivityInst
				.getVariable(FlowEngine.CONN_IS_PASS);
		if ((passNum != null && Integer.valueOf(passNum.toString()) == aiList
				.size())
				|| (isPass != null && isPass.toString().equals("true"))) { // 通过
			canCreateNext = true;
			// deleteOther(currentActivityInst.getModel()); // 删除共享任务

		} else { // 创建自己活动实例

			WfActivityInstance ai = new WfActivityInstance();
			ai.setActivityId(currentActivityInst.getActivity().getModel()
					.getId());
			ai.setCreateTime(currentActivityInst.getModel().getCreateTime());
			ai.setStartTime(currentActivityInst.getModel().getStartTime());
			ai.setEndTime(new Date());
			ai.setActor(currentActivityInst.getModel().getActor());
			ai.setState(currentActivityInst
					.getActivityInstState(FlowEngine.ACTIVITY_INST_END)); // 已结束
			ai.setName(currentActivityInst.getActivity().getModel().getName());
			ai.setOpinion(currentActivityInst.getModel().getOpinion());
			currentActivityInst.getModel().setOpinion(null);
			currentActivityInst.getModel().setStartTime(null);
			currentActivityInst.getModel().setActor(null);
			ai.setProcessInstId(processInstId);
			wfActivityInstanceDao.save(ai);
		}
		return canCreateNext;
	}

	/**
	 * 共享任务执行
	 * 
	 * @param wfActivityInstUserDao
	 * @param wfActivityInst
	 * @return
	 * @throws WfExecException
	 */
	public static boolean shareActivityExec(
			WfActivityInstUserDao wfActivityInstUserDao,
			WfActivityInstance wfActivityInst) throws WfExecException {

		// 删除共享任务
		wfActivityInstUserDao.deleteOhter(wfActivityInst);
		return true;
	}

	/**
	 * 普通活动执行
	 * 
	 * @param currentActivityInst
	 * @param processInstance
	 * @param nextWfActivity
	 * @param nextActorIds
	 * @param nextActorGroupIds
	 * @throws WfExecException
	 */
	public static ActivityInstance commonActivityExec(
			ProcessInstance processInstance, WfActivity nextWfActivity,
			Long[] nextActorIds, Long[] nextActorGroupIds)
			throws WfExecException {

		return activityExec(processInstance, nextWfActivity, nextActorIds,
				nextActorGroupIds);
	}

	/**
	 * 定时器执行
	 * 
	 * @param currentActivityInst
	 * @param wfVariableInstanceDao
	 * @return
	 * @throws WfExecException
	 */
	public static ActivityInstance timerRun(
			ActivityInstance currentActivityInst,
			WfVariableInstanceDao variableInstanceDao, WfVariableDao variableDao)
			throws WfExecException {

		// 任务定时器处理
		Integer timerPeriod = getTimerPeriod(currentActivityInst.getModel()
				.getId(), currentActivityInst.getModel().getActivityId(),
				variableInstanceDao, variableDao);
		
		if (timerPeriod != null) {

			Timer timer = new Timer();
			Object timerPeriodObj = currentActivityInst
					.getVariable(FlowEngine.TIMER_PERIOD);
			Integer period = 5 * 1000 * 60; // 默认5分钟
			if (timerPeriodObj == null
					|| timerPeriodObj.toString().trim().equals("")) {
				period = Integer.valueOf(timerPeriodObj.toString());
			}
			timer.schedule(new WfTimerTask(timerPeriod, currentActivityInst,
					timer), 0, period);
		}

		return currentActivityInst;
	}

	private static ActivityInstance activityExec(
			ProcessInstance processInstance, WfActivity nextWfActivity,
			Long[] nextActorIds, Long[] nextActorGroupIds)
			throws WfExecException {

		return processInstance.createActivityInstance(nextWfActivity,
				nextActorIds, nextActorGroupIds);
	}

	/**
	 * 邮件发送
	 * 
	 * @param mailService
	 * @param activityInst
	 * @throws WfCoreException
	 */
	public static void sendMail(MailSenderService mailService,
			ActivityInstance activityInst) throws WfCoreException {

		try {

			MailBean entity = new MailBean();
			String to = activityInst.getVariable(FlowEngine.MAIL_TO).toString();
			String subject = activityInst.getVariable(FlowEngine.MAIL_SUBJECT)
					.toString();
			String content = activityInst.getVariable(FlowEngine.MAIL_CONTENT)
					.toString();
			entity.setSubject(subject);
			entity.setContent(content);
			entity.setTo(to);
			
			Object sendType = activityInst.getVariable(FlowEngine.SEND_TYPE);
			if(sendType == null){
				throw new WfExecException("邮件发送类型不能为空");
			}
			
			//简单发送
			if(sendType.toString().equals(FlowEngine.SEND_TYPE_SIMPLE)){
				
				mailService.simpleSend(entity);
				
			//扩展发送	
			}else if(sendType.toString().equals(FlowEngine.SEND_TYPE_MIME)){
				
				//邮件附件处理
				Object attachmentObj = activityInst.getVariable(FlowEngine.MAIL_ATT);
				if(attachmentObj != null && 
						attachmentObj.toString().trim().equals("")){
					String attachment = attachmentObj.toString();
					JSONArray jsonArray = new JSONArray(attachment);
					for(int  i = 0; i < jsonArray.length(); i++){
						JSONObject jsonObj = jsonArray.getJSONObject(i);
						String name = jsonObj.getString("name");
						String path = jsonObj.getString("path");
						Attachment attchEntity = new Attachment();
						attchEntity.setName(name);
						attchEntity.setPath(path);
						entity.addAttachemnts(attchEntity);
					}
				}
				
				mailService.mineSend(entity);
			}else{
				throw new WfExecException(sendType.toString() +" 不是设置的邮件发送类型，" +
						"必须是 sendTypeSimple 或 sendTypeMime");
			}
			

		} catch (Exception e) {
			e.printStackTrace();
			throw new WfCoreException("发送邮件失败", e);
		}
	}

	/**
	 * 获得定时器间隔时间
	 * 
	 * @param activityInstId
	 * @param activityId
	 * @param variableInstDao
	 * @param variableDao
	 * @return
	 * @throws WfExecException
	 */
	public static Integer getTimerPeriod(Long activityInstId, Long activityId,
			WfVariableInstanceDao variableInstDao, WfVariableDao variableDao)
			throws WfExecException {

		String value = null;
		WfVariableInstanceSearch searchEntity = new WfVariableInstanceSearch();
		searchEntity.setName(FlowEngine.NODE_EXEC_TIMER);
		searchEntity.setActivityInstId(activityInstId);
		searchEntity.setSqlClause("t4.id is not null and t4.end_time is null");
		WfVariableInstanceForm form = variableInstDao.getForm(searchEntity);

		if (form == null) {
			WfVariableSearch variableSearch = new WfVariableSearch();
			variableSearch.setName(FlowEngine.NODE_EXEC_TIMER);
			variableSearch.setActivityId(activityId);
			variableSearch
					.setSqlClause("t3.id is not null ");
			WfVariableForm variableForm = variableDao.getForm(variableSearch);
			if (variableForm != null) {
				value = variableForm.getValue();
			}
		} else {
			value = form.getValue();
		}
		return StringUtils.isNotEmpty(value) ? Integer.valueOf(value) : null;
	}
}
